home *** CD-ROM | disk | FTP | other *** search
/ AOL File Library: 2,801 to 2,900 / aol-file-protocol-4400-2801-to-2900.zip / AOLDLs / C++ Files Library / Graphic Gems I, II & III (C_C++) / Graphics Gems C Code.sea / GemsII / sparse.c < prev    next >
Text File  |  1992-06-16  |  9KB  |  214 lines

  1. /*
  2.  *  Author: Jim Arvo
  3.  *
  4.  *  Corrected 11/05/91 to remove a redundant form.  The "C1" form as it
  5.  *  appeared in GemsII was unnecessary.
  6.  */
  7.  
  8. #include "GraphicsGems.h"
  9.  
  10. #define P1 (1<< 0)
  11. #define P2 (1<< 1)
  12. #define P3 (1<< 2)
  13. #define P4 (1<< 3)
  14. #define P5 (1<< 4)  
  15. #define P6 (1<< 5)
  16. #define RX (1<< 6)
  17. #define RY (1<< 7)
  18. #define RZ (1<< 8)
  19. #define C1 (1<< 9)
  20. #define C2 (1<<10)
  21. #define C3 (1<<11)
  22. #define C4 (1<<12)
  23. #define C5 (1<<13)
  24. #define C6 (1<<14)
  25.  
  26. /*-------------------------------------------------------------------------* 
  27.  *                                                                         *
  28.  * This function classifies a 3x3 matrix according to its zero structure.  * 
  29.  * It returns an unsigned integer in which each bit signifies a zero       *
  30.  * structure that describes the given matrix.  If all bits are zero it     *
  31.  * means the matrix is dense or does not fit any of these 15 forms.        *
  32.  *                                                                         *
  33.  *                                                                         *
  34.  *  Permutations:                                                          *
  35.  *                                                                         *
  36.  *  * 0 0     0 * 0     0 0 *     0 * 0     * 0 0      0 0 *               *
  37.  *  0 * 0     0 0 *     * 0 0     * 0 0     0 0 *      0 * 0               *
  38.  *  0 0 *     * 0 0     0 * 0     0 0 *     0 * 0      * 0 0               *
  39.  *                                                                         *
  40.  *   P1        P2        P3        P4        P5         P6                 *
  41.  *                                                                         *
  42.  *                                                                         *
  43.  *  Simple Rotations:                                                      *
  44.  *                                                                         *
  45.  *  * 0 0     * 0 *     * * 0                                              *
  46.  *  0 * *     0 * 0     * * 0                                              *
  47.  *  0 * *     * 0 *     0 0 *                                              *
  48.  *                                                                         *
  49.  *   RX        RY        RZ                                                *
  50.  *                                                                         *
  51.  *                                                                         *
  52.  *  Permutations of the simple rotations:                                  *
  53.  *                                                                         *
  54.  *  0 0 *     0 * *     0 * 0     * * 0     * 0 *     0 * *                *
  55.  *  * * 0     0 * *     * 0 *     0 0 *     * 0 *     * 0 0                *
  56.  *  * * 0     * 0 0     * 0 *     * * 0     0 * 0     0 * *                *
  57.  *                                                                         *
  58.  *   C1        C2        C3        C4        C5        C6                  *
  59.  *                                                                         *
  60.  *-------------------------------------------------------------------------*/
  61. unsigned int classify_matrix( M )
  62. Matrix3  M;
  63.     {
  64.     unsigned int form = 0xFFFF;
  65.  
  66.     /* Classify based on the diagonal elements. */
  67.  
  68.     if( M.element[0][0] != 0 ) form &= P1 | P5 | RX | RY | RZ | C4 | C5;
  69.     if( M.element[1][1] != 0 ) form &= P1 | P6 | RX | RY | RZ | C1 | C2;
  70.     if( M.element[2][2] != 0 ) form &= P1 | P4 | RX | RY | RZ | C3 | C6;
  71.  
  72.     /* Classify based on the upper triangular elements. */
  73.  
  74.     if( M.element[0][1] != 0 ) form &= P2 | P4 | RZ | C2 | C3 | C4 | C6;
  75.     if( M.element[0][2] != 0 ) form &= P3 | P6 | RY | C1 | C2 | C5 | C6;
  76.     if( M.element[1][2] != 0 ) form &= P2 | P5 | RX | C2 | C3 | C4 | C5;
  77.  
  78.     /* Classify based on the lower triangular elements. */
  79.  
  80.     if( M.element[1][0] != 0 ) form &= P3 | P4 | RZ | C1 | C3 | C5 | C6;
  81.     if( M.element[2][0] != 0 ) form &= P2 | P6 | RY | C1 | C2 | C3 | C4;
  82.     if( M.element[2][1] != 0 ) form &= P3 | P5 | RX | C1 | C4 | C5 | C6;
  83.  
  84.     /* If multiple classifications apply, return only one.  Doing this */
  85.     /* makes it possible to do a "switch" on the returned value.       */
  86.  
  87.     if( form & P1 ) return( P1 );
  88.     if( form & P2 ) return( P2 );
  89.     if( form & P3 ) return( P3 );
  90.     if( form & P4 ) return( P4 );
  91.     if( form & P5 ) return( P5 );
  92.     if( form & P6 ) return( P6 );
  93.     if( form & RX ) return( RX );
  94.     if( form & RY ) return( RY );
  95.     if( form & RZ ) return( RZ );
  96.     if( form & C1 ) return( C1 );
  97.     if( form & C2 ) return( C2 );
  98.     if( form & C3 ) return( C3 );
  99.     if( form & C4 ) return( C4 );
  100.     if( form & C5 ) return( C5 );
  101.     if( form & C6 ) return( C6 );
  102.     return( form );
  103.     }
  104.  
  105. /*-------------------------------------------------------------------------* 
  106.  *                                                                         *
  107.  * This routine transforms a vector "v" by a matrix "M" whose structure    *
  108.  * is specified by "form".  The result is returned in the vector "w".      *
  109.  * Note that "v" and "w" cannot be the same vector.                        *
  110.  *                                                                         *
  111.  * All zero elements must still be stored in the matrix "M"; the form      *
  112.  * argument simply indicates which ones to use.  Thus, no storage is       *
  113.  * saved in this implementation -- just time.                              *
  114.  *                                                                         *
  115.  *-------------------------------------------------------------------------*/
  116. void sparse_transform( M, form, v, w )
  117. Matrix3 M;
  118. unsigned int form;
  119. Vector3 *v;
  120. Vector3 *w;
  121.     {
  122.     switch( form )
  123.         {
  124.         case P1:
  125.             w->x = M.element[0][0] * v->x;
  126.             w->y = M.element[1][1] * v->y;
  127.             w->z = M.element[2][2] * v->z;
  128.             break;
  129.         case P2:
  130.             w->x = M.element[0][1] * v->x;
  131.             w->y = M.element[1][2] * v->y;
  132.             w->z = M.element[2][0] * v->z;
  133.             break;
  134.         case P3:
  135.             w->x = M.element[0][2] * v->x;
  136.             w->y = M.element[1][0] * v->y;
  137.             w->z = M.element[2][1] * v->z;
  138.             break;
  139.         case P4:
  140.             w->x = M.element[0][1] * v->x;
  141.             w->y = M.element[1][0] * v->y;
  142.             w->z = M.element[2][2] * v->z;
  143.             break;
  144.         case P5:
  145.             w->x = M.element[0][0] * v->x;
  146.             w->y = M.element[1][2] * v->y;
  147.             w->z = M.element[2][1] * v->z;
  148.             break;
  149.         case P6:
  150.             w->x = M.element[0][2] * v->x;
  151.             w->y = M.element[1][1] * v->y;
  152.             w->z = M.element[2][0] * v->z;
  153.             break;
  154.         case RX:
  155.             w->x = M.element[0][0] * v->x;
  156.             w->y = M.element[1][1] * v->y + M.element[1][2] * v->z;
  157.             w->z = M.element[2][1] * v->y + M.element[2][2] * v->z;
  158.             break;
  159.         case RY: 
  160.             w->x = M.element[0][0] * v->x + M.element[0][2] * v->z;
  161.             w->y = M.element[1][1] * v->y;
  162.             w->z = M.element[2][0] * v->x + M.element[2][2] * v->z;
  163.             break;
  164.         case RZ: 
  165.             w->x = M.element[0][0] * v->x + M.element[0][1] * v->y;
  166.             w->y = M.element[1][0] * v->x + M.element[1][1] * v->y;
  167.             w->z = M.element[2][2] * v->z;
  168.             break;
  169.         case C1: 
  170.             w->x = M.element[0][2] * v->z;
  171.             w->y = M.element[1][0] * v->x + M.element[1][1] * v->y;
  172.             w->z = M.element[2][0] * v->x + M.element[2][1] * v->y;
  173.             break;
  174.         case C2: 
  175.             w->x = M.element[0][1] * v->y + M.element[0][2] * v->z;
  176.             w->y = M.element[1][1] * v->y + M.element[1][2] * v->z;
  177.             w->z = M.element[2][0] * v->x;
  178.             break;
  179.         case C3: 
  180.             w->x = M.element[0][1] * v->y;
  181.             w->y = M.element[1][0] * v->x + M.element[1][2] * v->z;
  182.             w->z = M.element[2][0] * v->x + M.element[2][2] * v->z;
  183.             break;
  184.         case C4: 
  185.             w->x = M.element[0][0] * v->x + M.element[0][1] * v->y;
  186.             w->y = M.element[1][2] * v->z;
  187.             w->z = M.element[2][0] * v->x + M.element[2][1] * v->y;
  188.             break;
  189.         case C5: 
  190.             w->x = M.element[0][0] * v->x + M.element[0][2] * v->z;
  191.             w->y = M.element[1][0] * v->x + M.element[1][2] * v->z;
  192.             w->z = M.element[2][1] * v->y;
  193.             break;
  194.         case C6: 
  195.             w->x = M.element[0][1] * v->y + M.element[0][2] * v->z;
  196.             w->y = M.element[1][0] * v->x;
  197.             w->z = M.element[2][1] * v->y + M.element[2][2] * v->z;
  198.             break;
  199.         default: 
  200.             w->x = M.element[0][0] * v->x + M.element[0][1] * v->y + M.element[0][2] * v->z;
  201.             w->y = M.element[1][0] * v->x + M.element[1][1] * v->y + M.element[1][2] * v->z;
  202.             w->z = M.element[2][0] * v->x + M.element[2][1] * v->y + M.element[2][2] * v->z;
  203.             break;
  204.         } /* switch */
  205.  
  206.     } /* sparse_transform */
  207.  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.